home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / video / xevil-1.000 / xevil-1 / physical.h < prev    next >
C/C++ Source or Header  |  1995-07-29  |  35KB  |  1,468 lines

  1. // "physical.h"  Interior nodes of the physical object tree.  These classes
  2. // are never instantiated.
  3. // TAG: PH
  4.  
  5. /*    Copyright (C) 1994  Steve Hardt
  6.  
  7.       This program is free software; you can redistribute it and/or modify
  8.       it under the terms of the GNU General Public License as published by
  9.       the Free Software Foundation; either version 1, or (at your option)
  10.       any later version.
  11.  
  12.       This program is distributed in the hope that it will be useful,
  13.       but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.       GNU General Public License for more details.
  16.  
  17.       You should have received a copy of the GNU General Public License
  18.       along with this program; if not, write to the Free Software
  19.       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.       Steve Hardt 
  22.       hardts@athena.mit.edu hardts@media.mit.edu
  23.       hardts@r4002.3dem.bioch.bcm.tmc.edu
  24.       2043 McClendon
  25.       Houston, TX 77030
  26.       */
  27.  
  28. #ifndef PHYSICAL_H
  29. #define PHYSICAL_H
  30.  
  31. #ifndef NO_PRAGMAS
  32. #pragma interface
  33. #endif
  34.  
  35.  
  36. // Include Files
  37. #include "utils.h"
  38. #include "coord.h"
  39. #include "area.h"
  40. #include "world.h"
  41. #include "id.h"
  42. #include "intel.h"
  43. #include "locator.h"
  44.  
  45.  
  46. // Defines
  47. #define PH_ANIM_MAX 4
  48. #define PH_FRAME_MAX 7
  49. #define PH_WEAPONS_MAX 10
  50. #define PH_ITEMS_MAX 20
  51. #define PH_AMMO_UNLIMITED -1
  52.  
  53.  
  54.  
  55. // Other declarations
  56. enum PHsig {PH_NO_SIG, PH_NOT_SET, PH_ID_CHANGED};
  57.  
  58.  
  59.  
  60. // Class declarations
  61. class Protection;
  62. typedef Protection *ProtectionP;
  63.  
  64.  
  65. ////////// Physical
  66. /* The parent class of all physical objects. */
  67.  
  68. struct PhysicalContext {
  69.   Health health;
  70.   Mass mass;
  71.   ClassId classId;
  72.   const char *clas;
  73. };
  74.  
  75.  
  76. class Physical {
  77. public:
  78.   Physical(const PhysicalContext &,WorldP,LocatorP);
  79.   /* EFFECTS: Create a new, mapped physical with no Id with undefined area. */
  80.  
  81.   Physical();
  82.   /* NOTE: Should never be called. */
  83.  
  84.   virtual ~Physical();
  85.  
  86.   virtual const Area &get_area() = 0;
  87.  
  88.   virtual const Area &get_area_next() = 0;
  89.   /* NOTE: Should only be used by the Locator. */
  90.  
  91.   Health get_health() {return health;}
  92.  
  93.   Health get_health_next() {return healthNext;}
  94.   /* NOTE: Should only be used by the Locator to prepare for death.
  95.      Somewhat of a hack. */
  96.  
  97.   Health get_health_max() {return pc->health;}
  98.   Mass get_mass() {return mass;}
  99.   virtual Vel get_vel();
  100.   virtual Dir get_dir();
  101.  
  102.   ClassId get_class_id() {return pc->classId;}
  103.   const char *identify() {return pc->clas;}
  104.  
  105.   virtual int get_drawing_level();
  106.  
  107.   Boolean delete_me() {return deleteMe;}
  108.  
  109.   Boolean alive() {assert (health >= 0 || dieCalled); return health >= 0;}
  110.   /* NOTE: Is publicly known that (health >= 0) <=> alive.  So this function is
  111.    just for convenience. */
  112.  
  113.   Boolean die_called() 
  114. //  {assert (healthNext < 0 || !dieCalled);  return dieCalled;}
  115.     {return dieCalled;}
  116.   /* EFFECTS: Returns whether die() has been called or not.  Not clocked. */
  117.  
  118.   /* Should only be used for abstract classes.  Actual classes can be tested
  119.      for with get_class_id(). */
  120.   virtual Boolean is_moving();
  121.   virtual Boolean is_shot();
  122.   virtual Boolean is_item(); 
  123.   virtual Boolean is_shield();
  124.   virtual Boolean is_bomb();
  125.   virtual Boolean is_weapon();
  126.   virtual Boolean is_cutter();
  127.   virtual Boolean is_gun();
  128.   virtual Boolean is_creature(); 
  129.   virtual Boolean is_suicide();
  130.   virtual Boolean is_user();
  131.   virtual Boolean is_fighter();
  132.   virtual Boolean is_walking(); 
  133.   virtual Boolean is_sticky(); 
  134.   virtual Boolean is_flying();
  135.   virtual Boolean is_built_in();
  136.  
  137.   Boolean get_mapped() {return mapped;}
  138.  
  139.   virtual Boolean prickly();
  140.   /* NOTE: Prickly means that others are hurt by touching this Physical. */
  141.  
  142.   virtual Boolean collidable();
  143.   /* NOTE: This value never changes for an object. */
  144.  
  145.   const Acc *get_unit_accs() {return unitAccs;}
  146.   const Vel *get_unit_vels() {return unitVels;}
  147.  
  148.   Id get_id() {assert(idValid); return id;}
  149.  
  150.   PHsig get_id(Id &id);
  151.   /* MODIFIES: id */
  152.   /* EFFECTS: Set id to be the Id and return PH_NO_SIG if set.  Otherwise, 
  153.      return PH_NOT_SET. */
  154.  
  155.   PhysicalP get_dont_collide() {return dontCollide;}
  156.   /* EFFECTS: If there is another object that *this is not allowed to collide
  157.      with, return it.  Otherwise return NULL; */
  158.  
  159.   IntelP get_intel() {return intel;}
  160.   /* NOTE: Can be NULL. */
  161.  
  162.   Boolean get_flash() {return !flashTimer.ready();}
  163.  
  164.   Boolean get_quiet_death() {return quietDeath;}
  165.  
  166.   void set_command(ITcommand c) {command = c;}
  167.   /* EFFECTS: Sets the command to be c, overrides any previous command 
  168.      setting. */
  169.   /* NOTE: command is not clocked. */
  170.  
  171.   PHsig set_id(const Id &id);
  172.   /* EFFECTS: Set the Id to be id.  Return PH_NO_SIG if there was no previous
  173.      id.  Return PH_ID_CHANGED if there was a previous id.  The id is set in 
  174.      either case. */
  175.  
  176.   void set_dont_collide(PhysicalP other) {dontCollide = other;}
  177.   /* EFFECTS: *this will not be allowed to collide with other.  Any previous 
  178.      value will be overridden.  A setting of NULL disables this feature. */
  179.  
  180.   void set_intel(IntelP i) {intel = i;  if (i) i->set_id(id);}
  181.   /* REQUIRES: Object has been added to locator (has valid id.) */
  182.   /* NOTE: Can be NULL. */
  183.  
  184.   void set_health_next(Health h) {assert(alive()); healthNext = h;}
  185.  
  186.   virtual void heal();
  187.   /* EFFECTS: Called by MedKit. */
  188.   /* NOTE: Calls up the tree. */
  189.   
  190.   virtual void set_mapped_next(Boolean val);
  191.   /* NOTE: Should be ok to set the value to the previous value. */
  192.   /* NOTE: idempotent */
  193.   /* Calls up the tree. */
  194.  
  195.   void set_delete_me() {deleteMe = True;}
  196.   /* NOTE: Should only be called by self and Locator. */
  197.  
  198.   void flash();
  199.   /* EFFECTS: Object will be drawn for FLASH_TIME turns. */
  200.  
  201.   void set_no_death_delete() {noDeathDelete = True;}
  202.  
  203.   virtual void corporeal_attack(PhysicalP killer,int damage); 
  204.   virtual void heat_attack(PhysicalP,int heat,Boolean secondary = False);
  205.   /* NOTE: Sometimes call up the tree. */
  206.   /* NOTE: killer is the one responsible for causing the damage.  Can be 
  207.      NULL.  Adds kills to the killer. */
  208.   /* NOTE: Only the last call before the update cycle takes effect. */
  209.  
  210.   virtual Boolean swap_protect();
  211.   virtual Boolean frog_protect();
  212.   /* EFFECTS: Returns whether the Physical is protected from a swap or frog
  213.      attack.  May have side effects, so call only once per attack. */
  214.   /* NOTE: Using a Transmogifier is considered a swap attack. */
  215.   
  216.   virtual void avoid(PhysicalP);
  217.   virtual void collide(PhysicalP);
  218.   /* EFFECTS: Collision procedures.  avoid is called on the lighter of the two
  219.      objects.  collide is called on both objects. */
  220.   /* NOTE: Not always called up the tree. */
  221.  
  222.   void intelligence() {if (intel) intel->clock(this);}
  223.  
  224.   void kill_self() {healthNext = -1;}
  225.   /* NOTE: Called in act/collision_checks phase.  Do not call this in the 
  226.      die phase. (or update phase?) */
  227.  
  228.   virtual void set_quiet_death();
  229.   /* EFFECTS: When this dies, do not do any funny things like leaving corpses
  230.      or exploding or any other type of physical evidence. */
  231.   /* WARNING: When a User dies, it drops all weapons and items even if 
  232.      set_quiet_death() has been called.  This is somewhat of a hack. */
  233.   /* NOTE: Calls up the tree. */
  234.  
  235.   void virtual act();
  236.   /* EFFECTS: Action phase.  All next variables must be set here.  Commands 
  237.      are interpreted here.*/
  238.  
  239.   void virtual update(); 
  240.   /* EFFECTS: Set current variables to be the next ones.  No interactions 
  241.      between physical objects. */
  242.   
  243.   void virtual draw(Drawable buffer,Xvars &xvars,int dpyNum,
  244.             const Area &area) = 0;
  245.   /* REQUIRES: buffer is at least as big as area. */
  246.   /* EFFECTS: Draw the physical object in buffer.  buffer represents area. */
  247.   /* NOTE: Does not check for overlap */
  248.   /* NOTE: X variables initialized in draw.  Thus, if draw is never called for
  249.      a base class, the X variables never need to be initialized. */
  250.  
  251.   void virtual die();
  252.   /* EFFECTS:  If the *this dies a natural death (I.e. health < 0), then this
  253.      function is called.  Not called if *this is 
  254.      destroyed for any other reason.  E.g. end of game.  The default is to 
  255.      kill the intel and set_delete_me. */
  256.   /* NOTE: Called only in the die phase. */
  257.   /* NOTE: Calls up the tree. */
  258.   /* NOTE: Guaranteed to be called only once. */
  259.  
  260.  
  261.   virtual int get_weapons_num();
  262.   virtual int get_items_num(); 
  263.   /* NOTE: Returned value is not valid after current turn. */
  264.   
  265.   virtual PhysicalP get_weapon(int);
  266.   virtual PhysicalP get_item(int); 
  267.   virtual PhysicalP get_weapon_current();
  268.   virtual PhysicalP get_item_current();
  269.   /* NOTE: Can return NULL. */
  270.  
  271.   virtual Boolean ready();
  272.  
  273.  
  274.  
  275. #ifndef PROTECTED_IS_PUBLIC
  276. protected:
  277. #endif
  278.   WorldP get_world() {return world;}
  279.  
  280.   Boolean alive_next() {return healthNext >= 0;}
  281.  
  282.   LocatorP get_locator() {return locator;}
  283.  
  284.   const ITcommand &get_command() {return command;}
  285.   /* EFFECTS: Gets the command. */
  286.   /* NOTE: command is not clocked. */
  287.  
  288.   Boolean get_mapped_next() {return mappedNext;}
  289.  
  290.   void set_mass_next(Mass mss) {massNext = mss;}
  291.  
  292.  
  293. private:
  294.   void init_static();
  295.  
  296.   static Boolean staticValid;
  297.   static Acc unitAccs[CO_DIR_MAX]; 
  298.   static Vel unitVels[CO_DIR_MAX]; 
  299.   Boolean idValid;
  300.   Id id;
  301.   WorldP world;
  302.   LocatorP locator;
  303.   ITcommand command;
  304.   const PhysicalContext *pc; 
  305.   Health health, healthNext;
  306.   Mass mass, massNext;
  307.   PhysicalP dontCollide;
  308.   IntelP intel;
  309.   Boolean deleteMe;
  310.   Boolean mapped,mappedNext;
  311.   Boolean noDeathDelete; // Should set_delete_me be called at death.
  312.   Boolean dieCalled;
  313.   int heat, heatNext;
  314.   Boolean previousHeatWasSecondary;
  315.   Timer flashTimer;
  316.   Boolean quietDeath;
  317. };
  318. // PhysicalP defined in locator.h
  319.  
  320.  
  321.  
  322. ////////// Protection
  323. // Parent: Physical
  324. // Created by a Shield.  Protects a Moving against various types of attacks.
  325. // Not a subclass of Moving because we don't want to worry about hitting 
  326. // walls.
  327. struct ProtectionContext {
  328.   char *colorName;
  329.   PhysicalContext physicalContext;
  330. };
  331.  
  332.  
  333. class ProtectionXdata {
  334. public:
  335.   ProtectionXdata() {valid = False;}
  336.  
  337.   Pixel color[Xvars::DISPLAYS_MAX];
  338.   Boolean valid;
  339. };
  340.  
  341.  
  342. class Protection : public Physical {
  343. public:
  344.   Protection(const ProtectionContext &,ProtectionXdata &,
  345.          WorldP,LocatorP,const Area &);
  346.  
  347.   virtual Boolean collidable();
  348.   virtual const Area &get_area();
  349.   virtual const Area &get_area_next();
  350.  
  351.   void follow(const Area &);
  352.   /* NOTE: Can be called multiple times in one turn. */
  353.   /* EFFECTS: Called in act() phase by the Moving being protected. 
  354.    aNext is the next Area of the Moving.  Can be called before or after
  355.    this->act(). */
  356.  
  357.   virtual Boolean corporeal_protect(int damage) = 0;
  358.   virtual Boolean heat_protect(int heat,Boolean secondary) = 0;
  359.   /* EFFECTS: The Moving has received an attack.  Return wheter the Protection
  360.      will protect against the attack. */
  361.  
  362.   virtual void draw(Drawable,Xvars &,int,const Area &);
  363.  
  364.   virtual void act();
  365.   virtual void update();
  366.  
  367.  
  368. private:
  369.   enum {DELTA_MIN = -2,DELTA_MAX = 5};  // DELTA_MIN <= delta < DELTA_MAX
  370.  
  371.   virtual void init_x(Xvars &);
  372.  
  373.   const ProtectionContext *prc;
  374.   ProtectionXdata *pXdata;
  375.   int delta;  // When drawn, how far the Protection sticks out.
  376.   Area areaBaseNext;
  377.   Area area,areaNext;
  378. };
  379. // ProtectionP defined above.
  380.  
  381.  
  382.  
  383. ////////// Moving
  384. // Parent: Physical
  385. // Has all 19 directions.  Multiple pixmaps.  Can change size and position. 
  386. // Top speed is VEL_MAX.
  387.  
  388. /* Only sizes[CO_air] and offsets[CO_air] are required to be set.  
  389.    Gives initial size and offset. */
  390. struct MovingContext {
  391.   char *foreColorName;
  392.   Boolean foreWhiteDefault;
  393.   const char *backColorName;
  394.   Boolean backWhiteDefault;
  395.   int animMax[CO_DIR_MAX];
  396.   Size sizes[CO_DIR_MAX];
  397.   Size offsets[CO_DIR_MAX];
  398.   char *pixmapBits[CO_DIR_MAX][PH_ANIM_MAX];
  399.   char *maskBits[CO_DIR_MAX][PH_ANIM_MAX];
  400.   PhysicalContext physicalContext;
  401. };
  402.  
  403.  
  404. class MovingXdata {
  405. public:
  406.   MovingXdata() {valid = False;}
  407.   
  408.   Boolean valid;
  409.   Pixmap pixmaps[Xvars::DISPLAYS_MAX][CO_DIR_MAX][PH_ANIM_MAX],
  410.   masks[Xvars::DISPLAYS_MAX][CO_DIR_MAX][PH_ANIM_MAX];
  411. };
  412.  
  413.  
  414. class Moving: public Physical {
  415. public:
  416.   Moving(const MovingContext &m_c,
  417.      MovingXdata &x_data,
  418.      WorldP world,
  419.      LocatorP l,
  420.      const Pos &rawPos,
  421.      Dir dirInitial = CO_air);
  422.  
  423.   Moving();
  424.   /* NOTE: Should never be called. */
  425.  
  426.   virtual Boolean is_moving();
  427.  
  428.   virtual const Area &get_area();
  429.  
  430.   virtual const Area &get_area_next();
  431.   /* NOTE: Should only be used by the Locator or in a protected context. */
  432.  
  433.   virtual Vel get_vel();
  434.   const Pos &get_raw_pos() {return rawPos;}
  435.   virtual Dir get_dir();
  436.  
  437.   virtual Id get_protection();
  438.  
  439.   void set_vel_next(const Vel &vel) {velNext = vel;}
  440.   void set_vel_next(int zero) {assert (zero == 0); velNext.set_zero();}
  441.   /* EFFECTS: Sets the next velocity for the object to be vel.  Can be called
  442.      multiple times before update, only the last call is used. */
  443.  
  444.   void set_middle_next(const Pos &pos);
  445.   /* EFFECTS: Sets the middle of pos according to the current (not next) values
  446.      of dir, and area (for size). */
  447.   /* NOTE: May be called before or after act phase. */
  448.  
  449.   void relocate(const Pos &p);
  450.   /* EFFECTS: Moves the raw position of the Moving to p. Can and must be 
  451.      called outside of Locator::clock. */
  452.   /* REQUIRES: Must be relocated to an open area of the World. */
  453.   /* NOTE: Sets current and next values. */
  454.  
  455.   virtual void set_mapped_next(Boolean val);
  456.  
  457.   void set_extra_vel_next(const Vel &vel) 
  458.   {extraVelNext = vel; extraVelNextSet = True;}
  459.  
  460.   virtual void set_protection(const Id &);
  461.  
  462.   virtual void corporeal_attack(PhysicalP killer,int damage); 
  463.   virtual void heat_attack(PhysicalP,int heat,Boolean secondary = False);
  464.  
  465.   virtual void act();
  466.   virtual void update();
  467.   virtual void draw(Drawable,Xvars &,int,const Area &);
  468.   virtual void avoid(PhysicalP);
  469.   virtual void collide(PhysicalP);
  470.   virtual void die();
  471.  
  472.  
  473. #ifndef PROTECTED_IS_PUBLIC
  474. protected:
  475. #endif
  476.   Boolean hit_wall() {return hitWall;}
  477.   Boolean hit_wall_next() {return hitWallNext;}
  478.  
  479.   Dir get_dir_next() {return dirNext;}
  480.  
  481.   const MovingContext *get_moving_context() {return mc;}
  482.   Vel get_vel_next() {return velNext;}
  483.  
  484.   void set_vel(const Vel &v) {vel = v;}
  485.  
  486.   void set_dir(const Dir &d) {dir = d;}
  487.   /* NOTE: Only used by Lance for initialization. */
  488.  
  489.   void set_dir_next(const Dir &d) {dirNext = d;}
  490.  
  491.   void set_raw_pos_next(const Pos &rpos)
  492.     {rawPosNext = rpos; rawPosChanged = True;}
  493.  
  494.   void update_next();
  495.   /* EFFECTS: Compute areaNext and hitWallNext.  May modify rawPosNext or 
  496.      dirNext. */
  497.   /* NOTE: May be called more than once per turn. */
  498.  
  499.   virtual void get_pixmap_mask(int dpyNum,Pixmap &pixmap,Pixmap &mask,
  500.                    Dir dir,int animNum);
  501.   /* MODIFIES: pixmap, mask */
  502.   /* NOTE: Only used so that children of Moving can affect Moving's actions. */
  503.   
  504.   virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
  505.   /* MODIFIES: size, offset */
  506.   /* NOTE: Only used so that children of Moving can affect Moving's actions. */
  507.  
  508.   virtual void init_x(Xvars &);
  509.   /* NOTE: Now called up the tree. */
  510.  
  511.  
  512. private:
  513.   Boolean context_valid();
  514.   /* EFFECTS: Returns True if this->cx is valid, False otherwise. */
  515.  
  516.   float compute_collision(Mass m1,float v1,Mass m2,float v2);
  517.  
  518.  
  519.   MovingXdata *movingXdata;
  520.   int movingAnimNum;
  521.   Timer animTimer;
  522.   const MovingContext *mc;
  523.   Pos rawPos,rawPosNext; Boolean rawPosChanged;
  524.   Area area,areaNext;   
  525.   Dir dir,dirNext;
  526.   Vel vel,velNext; 
  527.   Boolean extraVelNextSet;
  528.   Vel extraVel,extraVelNext; // Follows clock in non-standard way.
  529.   Boolean hitWall,hitWallNext;
  530.   Id protection;
  531. };
  532. typedef Moving *MovingP;
  533.  
  534.  
  535.  
  536. ////////// Shot
  537. // Parent: Moving
  538.  
  539. struct ShotContext {
  540.   int damage; 
  541.   Speed speed;
  542.   MovingContext movingContext;
  543. };
  544.  
  545. typedef MovingXdata ShotXdata ;
  546.  
  547. class Shot: public Moving {
  548. public:
  549.   Shot(const ShotContext &,ShotXdata &,WorldP,LocatorP,
  550.        const Pos &,const Id &shooter,
  551.        Dir shotDir,Dir movingDir = CO_air);
  552.   
  553.   const Id &get_shooter() {return shooter;}
  554.  
  555.   virtual Boolean is_shot();
  556.  
  557.   virtual void avoid(PhysicalP other);
  558.   virtual void collide(PhysicalP other);
  559.  
  560.   virtual void act();
  561.  
  562.   static const Stats &get_stats() {return stats;}
  563.  
  564.  
  565. #ifndef PROTECTED_IS_PUBLIC
  566.  protected:
  567. #endif
  568.   int get_damage() {return context->damage;}
  569.  
  570.  
  571. private:
  572.   Id shooter;
  573.   const ShotContext *context;
  574.   static Stats stats;
  575. };
  576.  
  577.  
  578.  
  579. ////////// Falling
  580. // Parent: Moving
  581. // Moving with gravity.  Falls until it is blocked by the world.  
  582.  
  583. struct FallingContext {
  584.   MovingContext movingContext;
  585. };
  586.  
  587. typedef MovingXdata FallingXdata;
  588.  
  589. class Falling: public Moving {
  590. public:
  591.   Falling(const FallingContext &h_c,FallingXdata &x_data,
  592.       WorldP world,LocatorP l,const Pos &rawPos,
  593.       Dir dirInitial = CO_air);
  594.   
  595.   virtual void act();
  596. };
  597.  
  598.  
  599.  
  600. ////////// Touchable
  601. // Parent: Falling
  602. // Remembers if it has ever been touched by a Human controlled Physical.
  603.  
  604. struct TouchableContext {
  605.   FallingContext fallingContext;
  606. };
  607.  
  608. typedef FallingXdata TouchableXdata;
  609.  
  610. class Touchable: public Falling {
  611.  public:
  612.   Touchable(const TouchableContext &,TouchableXdata &x_data,
  613.         WorldP,LocatorP,const Pos &);
  614.  
  615.   virtual int get_drawing_level();
  616.   /* EFFECTS:  Touchable is drawn behind everything else. */
  617.   
  618.   Boolean wasTouched() {return touched;}
  619.   /* EFFECTS:  Has a Physical with Human intelligence touched the Xit. */
  620.   
  621.   virtual Boolean collidable();
  622.   virtual void act();
  623.  
  624.  
  625. private:
  626.   Boolean touched;
  627.   const TouchableContext *context;
  628. };
  629. typedef Touchable *TouchableP;
  630.  
  631.  
  632.  
  633. //////////// Heavy
  634. // Parent: Falling
  635. // Does damage to things it lands on.
  636.  
  637. struct HeavyContext {
  638.   int damage;
  639.   FallingContext fallingContext;
  640. };
  641.  
  642. typedef FallingXdata HeavyXdata;
  643.  
  644. class Heavy: public Falling {
  645.  public:
  646.   Heavy(const HeavyContext &h_c,
  647.     HeavyXdata &x_data,
  648.     WorldP world,
  649.     LocatorP l,
  650.     const Pos &rawPos);
  651.   
  652.   virtual void collide(PhysicalP);
  653.   /* EFFECTS: Crush things it falls on. */
  654.   
  655.  
  656.  private:
  657.   const HeavyContext *context;
  658. };
  659.  
  660.  
  661.  
  662. //////////// Item
  663. // Parent: Falling
  664. // 
  665. struct ItemContext {
  666.   Boolean persists;
  667.   FallingContext fallingContext;
  668. };
  669. typedef FallingXdata ItemXdata;
  670.  
  671.  
  672. class Item: public Falling {
  673. public:
  674.   Item(const ItemContext &c_x,
  675.        ItemXdata &x_data,
  676.        WorldP w,
  677.        LocatorP l,
  678.        const Pos &pos);
  679.   
  680.   Boolean is_item() {return True;}
  681.  
  682.   Boolean is_held() {return held;}
  683.   
  684.   Boolean can_take() {return canTake.ready() && !held && !cantTake;}
  685.   /* EFFECTS: Returns whether the object can be picked up. */
  686.  
  687.   virtual int get_drawing_level();
  688.   /* NOTE: Items are at drawing level 1. */
  689.  
  690.   Id get_holder_id();
  691.   /* EFFECTS: Returns the holder Id if held or an invalid Id if not held.  */
  692.  
  693.   void set_quiet_death();
  694.  
  695.   Boolean persists() {return context->persists;}
  696.  
  697.   virtual void follow_user(const Pos &userMiddle,Dir userDir);
  698.  
  699.   void taken(PhysicalP);
  700.   /* EFFECTS:  The object has been taken by another Physical. */
  701.   /* NOTE: Changes immediate externally visible state.  Should only be called
  702.      in the collision phase. */
  703.  
  704.   void dropped(PhysicalP);
  705.   /* EFFECTS:  The object has been dropped by another Physical. */
  706.   /* NOTE: Called by another object in the act phase. */
  707.   /* NOTE: Called in either the act or update phase. */
  708.   /* NOTE: Calls up the tree. */
  709.  
  710.   virtual void use(PhysicalP);
  711.   /* EFFECTS: p uses *this. */
  712.   /* NOTES: Called by another object in act phase.  Can also be called in
  713.      collide phase. (see AutoUse::collide)  Calls up the tree. */
  714.  
  715.   virtual void act();
  716.   
  717.   virtual void die();
  718.   
  719.   
  720. #ifndef PROTECTED_IS_PUBLIC
  721. protected:
  722. #endif
  723.   void set_cant_take() {cantTake = True;}
  724.   
  725.   
  726. private:
  727.   enum MESSAGE {NONE,USED,DESTROYED};
  728.  
  729.   Boolean held;
  730.   Id holderId; // Valid iff held.
  731.   Boolean dieMessage;
  732.   Timer canTake;
  733.   Boolean cantTake;
  734.   const ItemContext *context;
  735. };
  736. typedef Item *ItemP;
  737.  
  738.  
  739.  
  740. //////////// AutoUse
  741. // Parent: Item
  742. // Automatically gets used when it collides with a non-user creature.
  743. // WARNING: All children of this class must be able to be used by a non-user.
  744.  
  745. struct AutoUseContext {
  746.   ItemContext itemContext;
  747. };
  748. typedef ItemXdata AutoUseXdata;
  749.  
  750. class AutoUse : public Item {
  751. public:
  752.   AutoUse(const AutoUseContext &c_x,
  753.       AutoUseXdata &x_data,
  754.       WorldP w,
  755.       LocatorP l,
  756.       const Pos &pos);
  757.   
  758.   virtual void collide(PhysicalP);
  759. };
  760.  
  761.  
  762.  
  763. //////////// Shield
  764. // Parent: AutoUse
  765. struct ShieldContext {
  766.   AutoUseContext autoUseContext;
  767. };
  768. typedef AutoUseXdata ShieldXdata;
  769.  
  770. class Shield: public AutoUse {
  771. public:
  772.   Shield(const ShieldContext &,ShieldXdata &,
  773.      WorldP w,LocatorP l,const Pos &pos);
  774.   virtual Boolean is_shield();
  775.   
  776.   virtual void use(PhysicalP);
  777.  
  778.   static const Stats &get_stats() {return stats;}
  779.  
  780.   
  781. #ifndef PROTECTED_IS_PUBLIC
  782. protected:
  783. #endif
  784.   virtual ProtectionP create_protection(const Area&) = 0;
  785.   /* EFFECTS: Create the type of Protection specific to this type of Shield. */
  786.  
  787.  
  788. private:
  789.   static Stats stats;
  790. };
  791.  
  792.  
  793.  
  794. //////////// Animated
  795. // Parent: Item
  796. //
  797. struct AnimatedContext {
  798.   char *colorName;
  799.   Size size;
  800.   int animMax[PH_FRAME_MAX];
  801.   char *pixmapBits[PH_FRAME_MAX][PH_ANIM_MAX];
  802.   char *maskBits[PH_FRAME_MAX][PH_ANIM_MAX];
  803.   ItemContext itemContext;
  804. };
  805.  
  806.  
  807. class AnimatedXdata {
  808. public:
  809.   AnimatedXdata() {valid = False;}
  810.   Boolean valid;
  811.   Pixmap pixmaps[Xvars::DISPLAYS_MAX][PH_FRAME_MAX][PH_ANIM_MAX],
  812.   masks[Xvars::DISPLAYS_MAX][PH_FRAME_MAX][PH_ANIM_MAX];
  813.   ItemXdata itemXdata;
  814. }; 
  815.  
  816.  
  817. class Animated: public Item {
  818. public:
  819.   Animated(const AnimatedContext &,AnimatedXdata &,
  820.        WorldP,LocatorP,const Pos &);
  821.  
  822.  
  823. #ifndef PROTECTED_IS_PUBLIC
  824. protected:
  825. #endif
  826.   void set_frame(Frame fr) {frame = fr;}
  827.   void set_frame_next(Frame fr) {frameNext = fr;}
  828.   Frame get_frame() {return frame;}
  829.   
  830.   virtual void get_pixmap_mask(int dpyNum,Pixmap &pixmap,Pixmap &mask,
  831.                    Dir dir,int animNum);
  832.   virtual void get_size_offset_next(Size &size,Size &offset,
  833.                     Dir dirNext);
  834.   
  835.   virtual void init_x(Xvars &);
  836.   
  837.   virtual void update();
  838.  
  839.  
  840. private:
  841.   Boolean context_valid();
  842.  
  843.   AnimatedXdata *animatedXdata;
  844.   const AnimatedContext *ac;
  845.   Frame frame,frameNext;
  846.   int animatedAnimNum;
  847. };
  848.  
  849.  
  850.  
  851. //////////// Weapon
  852. // Parent: Item
  853. // 
  854. struct WeaponContext {
  855.   Boolean defaultable;
  856.   ItemContext itemContext;
  857. };
  858. typedef ItemXdata WeaponXdata;
  859. class Weapon;
  860. typedef Weapon *WeaponP;
  861.  
  862.  
  863. class Weapon: public Item {
  864. public:
  865.   Weapon(const WeaponContext &c_x,
  866.      WeaponXdata &x_data,
  867.      WorldP w,
  868.      LocatorP l,
  869.      const Pos &pos);
  870.   
  871.   Boolean is_weapon() {return True;}
  872.  
  873.   virtual Boolean ready();
  874.   /* EFFECTS: Can the weapon be fired now. */
  875.   /* NOTE: Sometimes calls up the tree.*/
  876.  
  877.   Boolean defaultable() {return wc->defaultable;}
  878.   /* EFFECTS: Is this a type of weapon that can safely be set automatically as
  879.      the current weapon.  E.g. You do not want to set a soul-swapper as the 
  880.      current weapon unless the user explicitly says so. */
  881.  
  882.   virtual int get_ammo() = 0;
  883.   virtual int get_ammo_max() = 0;
  884.   /* NOTE: Can return PH_AMMO_UNLIMITED. */
  885.  
  886.   virtual void fire(const Id &id,ITcommand command);
  887.   /* REQUIRES: command is a weapon command. */
  888.   /* EFFECTS: Fire the weapon according to the specified command.  id is the
  889.      physical firing the weapon.  */
  890.  
  891.   virtual void enter_scope_next(PhysicalP user);
  892.   virtual void leave_scope_next(PhysicalP user);
  893.   /* NOTE: Called during act(collide) or update phase. Should be just 
  894.      act(). */
  895.   /* NOTE: Calls up the tree. */
  896.   /* NOTE: ok to call multiple times in same turn, but must enter/leave scope
  897.      in proper order. */
  898.  
  899.   void take_ammo_from(WeaponP other);
  900.   /* EFFECTS: Take as much ammo as possible from the other weapon. */
  901.  
  902.  
  903. #ifndef PROTECTED_IS_PUBLIC
  904.  protected:
  905. #endif
  906.   Boolean entered_scope() {return enteredScope;}
  907.  
  908.   virtual void set_ammo(int) = 0;
  909.  
  910.  
  911. private:
  912.   const WeaponContext *wc;
  913.   Boolean enteredScope; // not clocked
  914. };
  915. // typedef Weapon *WeaponP; Defined above.
  916.  
  917.  
  918.  
  919. //////////// Cutter
  920. // Parent: Weapon
  921. // NOTE: Uses CO_center for cutter directly in front of user.
  922. struct CutterContext {
  923.   int damage;  // per turn
  924.   Size offsets[CO_DIR_MAX];  // From User's middle to Cutter's middle.
  925.  
  926.   char *unheldColorName;
  927.   Size unheldSize;
  928.   char *unheldPixmapBits;
  929.   char *unheldMaskBits;
  930.   WeaponContext weaponContext;
  931. };
  932.  
  933.  
  934. class CutterXdata {
  935.  public:
  936.   CutterXdata() {valid = False;}
  937.  
  938.   Boolean valid;
  939.   Pixmap unheldPixmap[Xvars::DISPLAYS_MAX],unheldMask[Xvars::DISPLAYS_MAX];
  940.   WeaponXdata weaponXdata;
  941. };
  942.  
  943.  
  944. class Cutter: public Weapon {
  945. public:
  946.   Cutter(const CutterContext &c_x,CutterXdata &x_data,
  947.      WorldP w,LocatorP l,const Pos &pos);
  948.   
  949.   virtual Boolean is_cutter();
  950.  
  951.   virtual Boolean ready();
  952.  
  953.   virtual int get_ammo();
  954.   virtual int get_ammo_max();
  955.  
  956.   virtual void get_pixmap_mask(int dpyNum,Pixmap &pixmap,Pixmap &mask,
  957.                    Dir dir,int animNum);
  958.   
  959.   virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
  960.  
  961.   virtual void set_ammo(int);
  962.  
  963.   virtual void follow_user(const Pos &,Dir);
  964.  
  965.   virtual void enter_scope_next(PhysicalP);
  966.   virtual void leave_scope_next(PhysicalP);
  967.  
  968.   virtual void collide(PhysicalP);
  969.  
  970.   virtual void update();
  971.  
  972.  
  973. #ifndef PROTECTED_IS_PUBLIC
  974.  protected: 
  975. #endif
  976.   virtual void init_x(Xvars &);
  977.  
  978.  
  979. private:
  980.   Dir dir_4_from_user_dir(Dir);
  981.  
  982.   Boolean inScope,inScopeNext;
  983.   Id killerId;  // Valid iff inScope.
  984.   CutterXdata *cutterXdata;
  985.   const CutterContext *context;
  986. };
  987.  
  988.  
  989.  
  990.  
  991. ////////// Creature
  992. // Parent: Moving
  993. // Moving with stances.  Can be affected by gravity.
  994. struct CreatureContext {
  995.   Speed crawlSpeed;
  996.   Speed centerSpeed; 
  997.   Speed airSpeed;
  998.   Speed climbSpeed;
  999.   Speed jump;
  1000.   Speed acceleration;
  1001.   Health corpseHealth; // A positive number.
  1002.  
  1003.   Size deadSize;
  1004.   Size deadOffset;
  1005.   char *deadPixmapBits;
  1006.   char *deadMaskBits;
  1007.   
  1008.   MovingContext movingContext;
  1009. };
  1010.  
  1011.  
  1012. struct CreatureXdata
  1013. {
  1014.   CreatureXdata() {valid = False;}
  1015.  
  1016.   Pixmap deadPixmap[Xvars::DISPLAYS_MAX],deadMask[Xvars::DISPLAYS_MAX];
  1017.   Boolean valid;
  1018.   MovingXdata movingXdata;
  1019. };
  1020.  
  1021.  
  1022. class Creature: public Moving {
  1023. public:
  1024.   Creature(const CreatureContext &m_c,
  1025.        CreatureXdata &x_data,
  1026.        WorldP world,
  1027.        LocatorP l,
  1028.        const Pos &rawPos);
  1029.  
  1030.   Creature();
  1031.   /* NOTE: Should never be called. */
  1032.  
  1033.   virtual Boolean is_creature();
  1034.   Stance get_stance() {return stance;}
  1035.   Boolean can_climb() {return canClimb;}
  1036.  
  1037.   const Hanging &get_hanging() {return hanging;}
  1038.   /* EFFECTS: Get the corner that the object is hanging off of, or CO_AIR if
  1039.      not hanging off a corner. */
  1040.  
  1041.   const Touching &get_touching_area() {return touching;}
  1042.   /* EFFECTS: The object's actual touching.  I.e. according to its area. */
  1043.  
  1044.   Grav get_grav() {return grav;}
  1045.  
  1046.   virtual void set_quiet_death();
  1047.   /* NOTE: Calling set_quiet_death on a corpse destroys it. */
  1048.  
  1049.   virtual void corporeal_attack(PhysicalP,int damage); 
  1050.   virtual void heat_attack(PhysicalP,int heat,Boolean secondary); 
  1051.  
  1052.   virtual void act();
  1053.   virtual void update();
  1054.   virtual void die();
  1055.  
  1056.   static const Stats &get_stats() {return stats;}
  1057.  
  1058.  
  1059. #ifndef PROTECTED_IS_PUBLIC
  1060. protected:
  1061. #endif
  1062.   Stance get_stance_next() {return stanceNext;}
  1063.  
  1064.   const CreatureContext *get_creature_context() {return cc;}
  1065.  
  1066.   Touching get_touching_stance();
  1067.   /* EFFECTS: The object's touching according to its stance. */
  1068.  
  1069.   time_t get_birth_time() {return birthTime;}
  1070.  
  1071.   virtual void get_pixmap_mask(int dpyNum,Pixmap &pixmap,Pixmap &mask,
  1072.                    Dir dir,int animNum);
  1073.   /* MODIFIES: pixmap, mask */
  1074.   
  1075.   virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
  1076.   /* MODIFIES: size, offset */
  1077.  
  1078.   void set_stance(const Stance &st) {stance = st;}
  1079.  
  1080.   void set_stance_next(const Stance &stance);
  1081.   /* EFFECTS: Sets the next stanceection for the object to be stance.  Can be
  1082.      called multiple times before update, only the last call is used. */
  1083.  
  1084.   void set_grav_next(const Grav &g)
  1085.     {gravNext = g;}
  1086.   /* EFFECTS: Sets the pull of gravity for the next turn to be grav. */
  1087.  
  1088.   void center_wsquare_x_next(const Loc &loc);
  1089.   /* REQUIRES: loc overlaps with the area, stanceNext set to CO_climb */
  1090.   /* EFFECTS: Tries to center the x position object on the wsquare at loc.  
  1091.      (May be bumped a bit if a wall prevents exact centering.) */
  1092.  
  1093.   void corner(const Hanging &hanging);
  1094.   /* REQUIRES: stanceNext is set to correspond to h.corner. */
  1095.   /* EFFECTS: Tries to move the object around the corner it is hanging off of.
  1096.      Note that hanging.corner is the initial corner, not the desired final 
  1097.      one. */
  1098.  
  1099.   virtual void init_x(Xvars &);
  1100.  
  1101.  
  1102. private:
  1103.   static Dir compute_dir(const Stance &stance,const Vel &vel);
  1104.   /* USES: nothing */
  1105.   /* EFFECTS: Return the dir corresponding to stance and vel. */
  1106.  
  1107.   Boolean context_valid();
  1108.  
  1109.   Touching touching;
  1110.   Hanging hanging;
  1111.   Boolean canClimb;
  1112.   Stance stance,stanceNext; 
  1113.   Grav grav,gravNext; 
  1114.   const CreatureContext *cc;
  1115.   Timer corpseTimer;
  1116.   CreatureXdata *creatureXdata;
  1117. //  Id killerId;   Now in Intel.
  1118.   time_t birthTime;
  1119.   static Stats stats;
  1120. };
  1121. typedef Creature *CreatureP;
  1122.  
  1123.  
  1124.  
  1125. /*//////// Grounded
  1126. //  Parent: Creature
  1127. Sticks to the ground only.  Affected by gravity.  Can't climb or jump. */
  1128. struct GroundedContext 
  1129. {
  1130.   int dummy;
  1131. }; 
  1132.  
  1133. struct GroundedXdata {};
  1134.  
  1135. class Grounded: public virtual Creature {
  1136.  public:
  1137.   Grounded(const GroundedContext &,GroundedXdata &);
  1138.   
  1139.   virtual void act();
  1140.   void _act();
  1141. };
  1142.  
  1143.  
  1144.  
  1145. /*//////// Suicide
  1146. // Parent: Creature
  1147. Kills self if the command IT_ITEM_USE is seen. */
  1148. struct SuicideContext
  1149. {
  1150.   int dummy;
  1151. };
  1152.  
  1153. struct SuicideXdata {};
  1154.  
  1155. class Suicide: public virtual Creature {
  1156.  public:
  1157.   Suicide(const SuicideContext &,SuicideXdata &);
  1158.  
  1159.   virtual Boolean is_suicide();
  1160.   
  1161.   virtual void act();
  1162.   void _act();
  1163. };
  1164.  
  1165.  
  1166.  
  1167. ////////// Hopping
  1168. // Parent: Creature
  1169. // 
  1170. struct HoppingContext 
  1171. {
  1172.   int dummy;
  1173. }; 
  1174.  
  1175. struct HoppingXdata {};
  1176.  
  1177. class Hopping: public virtual Creature {
  1178.  public:
  1179.   Hopping(const HoppingContext &,HoppingXdata &);
  1180.  
  1181.   virtual void act();
  1182. };
  1183.  
  1184.  
  1185.  
  1186. ////////// User
  1187. // Parent: Creature
  1188. // Holds and uses items and weapons.  The items and weapons are made to follow
  1189. // the User. 
  1190. struct UserContext 
  1191. {
  1192.   int dummy;
  1193. };  
  1194.  
  1195. struct UserXdata {};
  1196.  
  1197.  
  1198. class User: public virtual Creature {
  1199. public:
  1200.   User(const UserContext &,UserXdata &);
  1201.  
  1202.   virtual Boolean is_user();
  1203.  
  1204.   virtual int get_weapons_num();
  1205.   virtual int get_items_num(); 
  1206.   /* NOTE: Returned value is not valid after current turn. */
  1207.   
  1208.   virtual PhysicalP get_weapon(int);
  1209.   virtual PhysicalP get_item(int); 
  1210.   virtual PhysicalP get_weapon_current();
  1211.   virtual PhysicalP get_item_current();
  1212.   /* NOTE: Can return NULL. */
  1213.  
  1214.   virtual void set_mapped_next(Boolean val);
  1215.   /* EFFECTS: Bring current weapon in/out of scope and then change mapped. */
  1216.  
  1217.   virtual void act();
  1218.   void _act();
  1219.  
  1220.   virtual void collide(PhysicalP other);
  1221.   Boolean _collide(PhysicalP);
  1222.  
  1223.   virtual void die();
  1224.   void _die();
  1225.  
  1226.  
  1227. #ifndef PROTECTED_IS_PUBLIC
  1228.  protected:
  1229. #endif
  1230.   Boolean has_weapon(Weapon **weapon,ClassId classId);
  1231.   /* MODIFIES: weapon */
  1232.   /* EFFECTS: Like has_weapon(ClassId) except will return the 
  1233.      weapon in weapon if not NULL. */
  1234.  
  1235.  
  1236. private:
  1237.   int defaultable_weapon();
  1238.   /* REQUIRES: weaponsNum and weapons are properly updated. */
  1239.   /* EFFECTS: Returns the index of a wepon in weapons that is defaultable or
  1240.      weaponsNum if there is none. */
  1241.  
  1242.  
  1243.   Id weapons[PH_WEAPONS_MAX];
  1244.   int weaponsNum;
  1245.   int weaponCurrent; // weaponCurrent == weaponsNum if no selected weapon.
  1246.   //  Memory of previous weapon dir is now in ui.
  1247.  
  1248.   Id items[PH_ITEMS_MAX];
  1249.   int itemsNum;
  1250.   int itemCurrent; // itemCurrent == itemsNum if no selected item.
  1251. };
  1252. typedef User *UserP;
  1253.  
  1254.  
  1255.  
  1256. ////////// Fighter
  1257. // Parent: Creature
  1258. // Can attack in different directions.
  1259. struct FighterContext {
  1260.   char *colorName;
  1261.   int slide;
  1262.   int jumpHorizontal;
  1263.   int jumpVertical;
  1264.   int damageStuck;
  1265.   int damageFree;
  1266.  
  1267.   Size sizes[CO_DIR_MAX];
  1268.   Size offsets[CO_DIR_MAX];
  1269.   Size hotSpots[CO_DIR_MAX];  // Must add in offset to use.
  1270.   char *pixmapBits[CO_DIR_MAX];
  1271.   char *maskBits[CO_DIR_MAX];
  1272. };
  1273.  
  1274.  
  1275. class FighterXdata {
  1276. public:
  1277.   FighterXdata() {valid = False;}
  1278.  
  1279.   Boolean valid;
  1280.   Pixmap pixmaps[Xvars::DISPLAYS_MAX][CO_DIR_MAX],
  1281.   masks[Xvars::DISPLAYS_MAX][CO_DIR_MAX];
  1282. };
  1283.  
  1284.  
  1285. class Fighter: public virtual Creature {
  1286. public:
  1287.   Fighter(const FighterContext &f_c,FighterXdata &x_data);
  1288.  
  1289.   virtual Boolean is_fighter();
  1290.  
  1291.   virtual void get_pixmap_mask(int dpyNum,Pixmap &pixmap,Pixmap &mask,
  1292.                    Dir dir,int animNum);
  1293.   
  1294.   virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
  1295.  
  1296.   virtual void act();
  1297.   void _act();
  1298.  
  1299.   virtual void update();
  1300.   void _update();
  1301.  
  1302.   virtual void collide(PhysicalP other);
  1303.   Boolean _collide(PhysicalP);
  1304.  
  1305.  
  1306. #ifndef PROTECTED_IS_PUBLIC
  1307. protected:
  1308. #endif
  1309.   virtual void init_x(Xvars &);
  1310.  
  1311.  
  1312. private:
  1313.   Attack dir_to_attack(Dir dir);
  1314.  
  1315.   void attack_stuck(Dir dir,Stance stance);
  1316.   void attack_free_horizontal(Dir dir);
  1317.   /* NOTE: Does not zero vertical velocity. */
  1318.  
  1319.   void attack_free_vertical(Dir dir);
  1320.   /* NOTE: Vertical velocity only. */
  1321.  
  1322.   FighterXdata *fighterXdata;
  1323.   const FighterContext *fc;
  1324.   Attack attack, attackNext;
  1325.   Timer stuckTimer;
  1326. };
  1327.  
  1328.  
  1329.  
  1330. ////////// Walking
  1331. // Parent: Creature
  1332. // Sticks to the ground only.  Affected by gravity.
  1333. struct WalkingContext 
  1334. {
  1335.   int dummy;
  1336. }; 
  1337.  
  1338. struct WalkingXdata {};
  1339.  
  1340. class Walking: public virtual Creature {
  1341. public:
  1342.   Walking(const WalkingContext &,WalkingXdata &);
  1343.  
  1344.   virtual Boolean is_walking() {return True;}
  1345.  
  1346.   virtual void act();
  1347.   void _act();
  1348.  
  1349.  
  1350. private:
  1351.   Pos rawPosPrev;
  1352.   Vel velPrev;
  1353. };
  1354.  
  1355.  
  1356.  
  1357. ////////// Sticky
  1358. // Parent: Creature
  1359. // Sticks to and walks on flat surfaces in four directions.  Affected by 
  1360. // gravity.
  1361. struct StickyContext 
  1362. {
  1363.   int dummy;
  1364. };  
  1365.  
  1366. struct StickyXdata {};
  1367.  
  1368. class Sticky: public virtual Creature {
  1369. public:
  1370.   Sticky(const StickyContext &,StickyXdata &);
  1371.   
  1372.   virtual Boolean is_sticky();
  1373.  
  1374.   virtual void act();
  1375.   void _act();
  1376.  
  1377.  
  1378. #ifndef PROTECTED_IS_PUBLIC
  1379. protected:
  1380. #endif
  1381.   Boolean want_corner(const Corner &corner);
  1382.   /* EFFECTS: Returns True if the object should go around the given corner,
  1383.      False otherwise.  corner is the initial, not final corner.*/
  1384.  
  1385.   Stance cornered_stance(const Hanging &h);
  1386.   /* EFFECTS: Returns the stance to take in order to go around the corner
  1387.      of h. */
  1388.  
  1389.   void set_want_corner(const Corner &c1) 
  1390.     {wantCorner1 = c1; wantCorner2 = CO_air;}
  1391.   void set_want_corner(const Corner &c1,const Corner &c2) 
  1392.     {wantCorner1 = c1; wantCorner2 = c2;}
  1393.   /* EFFECTS: Tell the object that it should go around a corner if possible.
  1394.      The given values are in effect until changed. */
  1395.   /* NOTE: set_want_corner(CO_air) should be used to disable cornering. */
  1396.  
  1397.  
  1398. private:
  1399.   Corner wantCorner1,wantCorner2;
  1400. };
  1401.  
  1402.  
  1403.  
  1404. ////////// Flying
  1405. // Parent: Creature
  1406. // Floats around.  Can walk on the ground.
  1407. struct FlyingContext 
  1408. {
  1409.   int gravTime;
  1410. };  
  1411.  
  1412. struct FlyingXdata {};
  1413.  
  1414. class Flying: public virtual Creature {
  1415. public:
  1416.   Flying(const FlyingContext &,FlyingXdata &);
  1417.   
  1418.   virtual Boolean is_flying();
  1419.  
  1420.   virtual void act();
  1421.   void _act();
  1422.  
  1423.  
  1424. private:
  1425.   Timer gravTimer;
  1426.   const FlyingContext *context;
  1427. };
  1428.  
  1429.  
  1430.  
  1431. ////////// BuiltIn
  1432. // Parent: Creature
  1433. // Has a directional built in weapon.
  1434. struct BuiltInContext 
  1435. {
  1436.   int shotTime;
  1437. };  
  1438.  
  1439. struct BuiltInXdata {};
  1440.  
  1441. class BuiltIn: public virtual Creature {
  1442. public:
  1443.   BuiltIn(const BuiltInContext &,BuiltInXdata &);
  1444.   
  1445.   virtual Boolean is_built_in();
  1446.  
  1447.   virtual Boolean ready();
  1448.   /* EFFECTS: Is the BuiltIn ready to fire. */
  1449.  
  1450.   virtual void act();
  1451.   void _act();
  1452.  
  1453.  
  1454. #ifndef PROTECTED_IS_PUBLIC
  1455. protected:
  1456. #endif
  1457.   virtual Size get_shot_size(Dir) = 0;
  1458.  
  1459.   virtual PhysicalP create_shot(const Pos &,Dir) = 0;
  1460.  
  1461.  
  1462. private:
  1463.   Timer shotTimer;
  1464. };
  1465. typedef BuiltIn *BuiltInP;
  1466.  
  1467. #endif
  1468.